<template>
  <div class="file-upload">
    <!-- <button class="btn btn-primary" @click="triggerUpload">
      <span v-if="fileStatus == 'loading'">正在上传</span>
      <span v-else-if="fileStatus == 'success'">成功</span>
      <span v-else-if="fileStatus == 'error'">失败</span>
      <span v-else>点击上传</span>
    </button> -->
    <div
      class="file-upload-container"
      @click.prevent="triggerUpload"
      v-bind="$attrs"
    >
      <slot v-if="fileStatus === 'loading'" name="loading">
        <button class="btn btn-primary" disabled>正在上传...</button>
      </slot>
      <slot
        v-else-if="fileStatus === 'success'"
        name="uploaded"
        :uploadedData="uploadedData"
      >
        <button class="btn btn-primary">上传成功</button>
      </slot>
      <slot
        name="uploaded"
        v-else-if="fileStatus === 'error'"
        :uploadedData="uploadedData"
      >
        <button class="btn btn-primary">上传失败</button>
      </slot>
      <slot v-else name="default">
        <button class="btn btn-primary">点击上传</button>
      </slot>
    </div>
    <input
      type="file"
      class="file-input d-none"
      ref="fileInput"
      @change="handleFileChange"
    />
  </div>
</template>

<script lang="ts">
import axios from 'axios'
import { defineComponent, PropType, ref, watch } from 'vue'
type UploadStatus = 'ready' | 'loading' | 'success' | 'error'
type CheckFunction = (file: File) => boolean
export default defineComponent({
  emits: ['file-uploaded', 'file-uploaded-error'],
  props: {
    beforeUpload: {
      type: Function as PropType<CheckFunction>
    },
    uploaded: {
      type: Object
    }
  },

  setup(props, context) {
    const uploadedData = ref(props.uploaded)
    const fileInput = ref<null | HTMLInputElement>(null)
    const fileStatus = ref<UploadStatus>('ready')
    const triggerUpload = () => {
      console.log('trigger')

      if (fileInput.value) {
        console.log(fileInput.value)

        fileInput.value.click()
      }
    }
    watch(
      () => props.uploaded,
      (newValue) => {
        if (newValue) {
          fileStatus.value = 'success'
          uploadedData.value = newValue
        }
      }
    )
    const handleFileChange = (e: Event) => {
      const target = e.target as HTMLInputElement
      const files = target.files
      if (files) {
        // 检查是否有
        if (props.beforeUpload) {
          const result = props.beforeUpload(files[0])
          if (!result) {
            return
          }
        }
        fileStatus.value = 'loading'
        const uploadFile = files[0]
        const formData = new FormData()
        formData.append(uploadFile.name, uploadFile)

        axios
          .post('/upload', formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          })
          .then((res) => {
            console.log(res.data)
            uploadedData.value = res.data || []
            context.emit('file-uploaded', res.data)
            fileStatus.value = 'success'
          })
          .catch((e) => {
            uploadedData.value = e
            context.emit('file-uploaded', e)
            fileStatus.value = 'error'
          })
          .finally(() => {
            // 文本节点的value
            fileInput.value.value = ''
          })
      }
    }
    return {
      triggerUpload,
      fileInput,
      handleFileChange,
      fileStatus,
      uploadedData
    }
  }
})
</script>

<style scoped></style>
